package main

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"github.com/iGoogle-ink/gopay"
	"github.com/iGoogle-ink/gopay/alipay"
	"github.com/iGoogle-ink/gopay/wechat"
	"fmt"
	"log"
	"os"
	"time"
	"../config"
)

func main() {
	wxconf, _ := config.GetPayConf("wxpay")
	aliconf, _ := config.GetPayConf("alipay")
	isProd := config.GetEnv()

	wxc := wechat.NewClient(wxconf.AppId, wxconf.MchId, wxconf.ApiKey, isProd)
	//wxc.AddCertFilePath(certFilePath, keyFilePath, pkcs12FilePath)
	alic := alipay.NewClient(aliconf.AppId, aliconf.PrivateKey, isProd)

	logconf, _ := config.GetLogConf()
	f, _ := os.Create(logconf.CronPath)
	log.SetOutput(f)
	dbconf, _ := config.GetDBConf("mysql")
	constr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true",
		dbconf.User,
		dbconf.Password,
		dbconf.Host,
		dbconf.Port,
		dbconf.DB)
	//fmt.Println(constr)
	db, err := sql.Open("mysql", constr)
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()
	for {
		var no string
		var otype int8
		t := time.Now().Add(-time.Minute * 15)
		stmt, err := db.Prepare(`SELECT out_trade_no, order_type FROM goadmin_order WHERE status=? AND create>UNIX_TIMESTAMP(?)`)
		if err != nil {
			time.Sleep(time.Second * 3)
			continue
		}
		rows, err := stmt.Query(0, t.Format("2006-01-02 15:04:05"))
		if err != nil {
			time.Sleep(time.Second * 3)
			continue
		}
		stmt.Close()
		bm := make(gopay.BodyMap)
		for rows.Next() {
			fmt.Println("processing...")
			err = rows.Scan(&no, &otype)
			if err != nil {
				log.Fatalln("query error :", err)
			}
			bm.Set("out_trade_no", no)
			if otype == 0 {
				rsp, err := wxc.QueryOrder(bm)
				if err != nil {
					log.Fatalln("wxpay queryorder error:", err)
				}
				if rsp.ReturnCode == "SUCCESS" {
					if rsp.ResultCode == "SUCCESS" {
						// store payment info
						stmt, err = db.Prepare(`INSERT INTO goadmin_payment(appid, mch_id, openid, buyer_account, out_trade_no, transaction_id,
		is_subscribe, trade_type, bank_type, total_fee, cash_fee, time_end) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)`)
						if err != nil {
							log.Fatalln(no, err)
						}
						_, err = stmt.Exec(rsp.Appid, rsp.MchId, rsp.Openid, "", rsp.OutTradeNo, rsp.TransactionId,
							rsp.IsSubscribe, rsp.TradeType, rsp.BankType, rsp.TotalFee, rsp.CashFee, rsp.TimeEnd)
						if err != nil {
							log.Fatalln(rsp, err)
						}
						stmt.Close()
						// update order status
						tx, err := db.Begin()
						if err != nil {
							log.Fatalln("begin translation err:", err)
						}
						stmt, err = tx.Prepare(`UPDATE goadmin_order SET status=? WHERE out_trade_no=?`)
						if err != nil {
							tx.Rollback()
							log.Fatalln("update order fail ", rsp.OutTradeNo, err)
						}
						_, err = stmt.Exec(1, rsp.OutTradeNo)
						if err != nil {
							tx.Rollback()
							log.Fatalln("update order fail ", rsp.OutTradeNo, err)
						} else {
							tx.Commit()
						}
						return
					}
					log.Fatalf("wx response err code:%v, des:%v\n", rsp.ErrCode, rsp.ErrCodeDes)
				}
			}
			if otype == 1 {
				rsp, err := alic.TradeQuery(bm)
				if err != nil {
					log.Fatalln("alipay queryorder error:", err)
				}
				if rsp.Response.Code == "10000" {
					if rsp.Response.TradeStatus == "WAIT_BUYER_PAY" {
						// store payment info
						stmt, err = db.Prepare(`INSERT INTO goadmin_payment(appid, mch_id, openid, buyer_account, out_trade_no, transaction_id,
		is_subscribe, trade_type, bank_type, total_fee, cash_fee, time_end) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)`)
						if err != nil {
							log.Fatalln(bm.EncodeGetParams(), err)
						}
						_, err = stmt.Exec(aliconf.AppId, rsp.Response.StoreId, rsp.Response.BuyerUserId, rsp.Response.BuyerLogonId,
							rsp.Response.OutTradeNo, rsp.Response.TradeNo, "", "", rsp.Response.TotalAmount, rsp.Response.BuyerPayAmount,
							time.Now().Format("20060102150405"))
						if err != nil {
							log.Fatalln(rsp, err)
						}
						stmt.Close()
					}
					// update order status
					tx, err := db.Begin()
					if err != nil {
						log.Fatalln("begin translation err:", err)
					}
					stmt, err := tx.Prepare(`UPDATE goadmin_order SET status=? WHERE out_trade_no=?`)
					if err != nil {
						tx.Rollback()
						log.Fatalln("update order fail ", rsp.Response.OutTradeNo, err)
					}
					_, err = stmt.Exec(1, rsp.Response.OutTradeNo)
					if err != nil {
						tx.Rollback()
						log.Fatalln("update order fail ", rsp.Response.OutTradeNo, err)
					} else {
						tx.Commit()
					}
				}
			}
		}
		fmt.Println("sleeping...")
		time.Sleep(time.Minute * 15)
	}
}
